//! # 死信队列测试模块

use super::*;
use std::collections::HashMap;
use tokio::time::Duration;

#[tokio::test]
async fn test_dead_letter_queue_creation() {
    let config = DeadLetterConfig::default();
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let stats = dlq.get_stats().await.unwrap();
    assert_eq!(stats.total_dead_letters, 0);
    assert_eq!(stats.pending_retry_count, 0);
}

#[tokio::test]
async fn test_add_dead_letter_message() {
    let config = DeadLetterConfig::default();
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message = serde_json::json!({
        "topic": "test-topic",
        "payload": "test message",
        "id": "msg-123"
    });
    
    let id = dlq.add_dead_letter(
        message.clone(),
        "Processing failed".to_string(),
        Some({
            let mut details = HashMap::new();
            details.insert("error_code".to_string(), "500".to_string());
            details
        })
    ).await.unwrap();
    
    // 验证消息已添加
    let dead_letter = dlq.get_dead_letter(&id).await.unwrap().unwrap();
    assert_eq!(dead_letter.failure_reason, "Processing failed");
    assert_eq!(dead_letter.source_topic, "test-topic");
    assert_eq!(dead_letter.retry_count, 0);
    assert!(dead_letter.next_retry_at.is_some());
    
    // 验证统计信息
    let stats = dlq.get_stats().await.unwrap();
    assert_eq!(stats.total_dead_letters, 1);
    assert_eq!(stats.pending_retry_count, 1);
}

#[tokio::test]
async fn test_get_retry_candidates() {
    let config = DeadLetterConfig::default();
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    // 添加两条消息
    let message1 = serde_json::json!({"topic": "test-1", "id": "msg-1"});
    let message2 = serde_json::json!({"topic": "test-2", "id": "msg-2"});
    
    dlq.add_dead_letter(message1, "Failure 1".to_string(), None).await.unwrap();
    dlq.add_dead_letter(message2, "Failure 2".to_string(), None).await.unwrap();
    
    // 获取重试候选者（由于延迟策略，应该没有立即可重试的）
    let candidates = dlq.get_retry_candidates(10).await.unwrap();
    // 由于有默认延迟，候选者应该为空
    assert_eq!(candidates.len(), 0);
}

#[tokio::test]
async fn test_retry_message() {
    let config = DeadLetterConfig::default();
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message = serde_json::json!({"topic": "test", "id": "msg-1"});
    let id = dlq.add_dead_letter(message, "Initial failure".to_string(), None).await.unwrap();
    
    // 尝试重试
    let result = dlq.retry_message(&id).await.unwrap();
    assert!(result); // 应该成功开始重试
    
    // 验证重试计数增加
    let dead_letter = dlq.get_dead_letter(&id).await.unwrap().unwrap();
    assert_eq!(dead_letter.retry_count, 1);
    assert!(dead_letter.last_retry_at.is_some());
}

#[tokio::test]
async fn test_retry_message_max_attempts() {
    let mut config = DeadLetterConfig::default();
    config.max_retry_attempts = 2; // 设置最大重试次数为2
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message = serde_json::json!({"topic": "test", "id": "msg-1"});
    let id = dlq.add_dead_letter(message, "Initial failure".to_string(), None).await.unwrap();
    
    // 第一次重试
    assert!(dlq.retry_message(&id).await.unwrap());
    // 第二次重试
    assert!(dlq.retry_message(&id).await.unwrap());
    // 第三次重试应该失败（超过最大次数）
    assert!(!dlq.retry_message(&id).await.unwrap());
}

#[tokio::test]
async fn test_mark_retry_success() {
    let config = DeadLetterConfig::default();
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message = serde_json::json!({"topic": "test", "id": "msg-1"});
    let id = dlq.add_dead_letter(message, "Initial failure".to_string(), None).await.unwrap();
    
    // 标记重试成功
    dlq.mark_retry_success(&id).await.unwrap();
    
    // 消息应该被移除
    let dead_letter = dlq.get_dead_letter(&id).await.unwrap();
    assert!(dead_letter.is_none());
    
    // 统计信息应该更新
    let stats = dlq.get_stats().await.unwrap();
    assert_eq!(stats.retry_success_count, 1);
    assert_eq!(stats.pending_retry_count, 0);
}

#[tokio::test]
async fn test_mark_retry_failure() {
    let config = DeadLetterConfig::default();
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message = serde_json::json!({"topic": "test", "id": "msg-1"});
    let id = dlq.add_dead_letter(message, "Initial failure".to_string(), None).await.unwrap();
    
    // 标记重试失败
    dlq.mark_retry_failure(&id, "Retry failed".to_string()).await.unwrap();
    
    // 消息应该仍然存在，但失败原因更新
    let dead_letter = dlq.get_dead_letter(&id).await.unwrap().unwrap();
    assert_eq!(dead_letter.failure_reason, "Retry failed");
    
    // 统计信息应该更新
    let stats = dlq.get_stats().await.unwrap();
    assert_eq!(stats.retry_failure_count, 1);
}

#[tokio::test]
async fn test_remove_dead_letter() {
    let config = DeadLetterConfig::default();
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message = serde_json::json!({"topic": "test", "id": "msg-1"});
    let id = dlq.add_dead_letter(message, "Failure".to_string(), None).await.unwrap();
    
    // 删除消息
    dlq.remove_dead_letter(&id).await.unwrap();
    
    // 消息应该不存在
    let dead_letter = dlq.get_dead_letter(&id).await.unwrap();
    assert!(dead_letter.is_none());
}

#[tokio::test]
async fn test_cleanup_expired() {
    let mut config = DeadLetterConfig::default();
    config.message_ttl_secs = 1; // 设置很短的TTL
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message = serde_json::json!({"topic": "test", "id": "msg-1"});
    let id = dlq.add_dead_letter(message, "Failure".to_string(), None).await.unwrap();
    
    // 等待消息过期
    tokio::time::sleep(Duration::from_secs(2)).await;
    
    // 清理过期消息
    let cleaned_count = dlq.cleanup_expired().await.unwrap();
    assert_eq!(cleaned_count, 1);
    
    // 消息应该被清理
    let dead_letter = dlq.get_dead_letter(&id).await.unwrap();
    assert!(dead_letter.is_none());
}

#[tokio::test]
async fn test_dead_letter_queue_capacity_limit() {
    let mut config = DeadLetterConfig::default();
    config.max_dead_letter_messages = 2; // 设置容量限制
    let dlq = InMemoryDeadLetterQueue::new(config);
    
    let message1 = serde_json::json!({"topic": "test", "id": "msg-1"});
    let message2 = serde_json::json!({"topic": "test", "id": "msg-2"});
    let message3 = serde_json::json!({"topic": "test", "id": "msg-3"});
    
    // 添加两条消息应该成功
    dlq.add_dead_letter(message1, "Failure 1".to_string(), None).await.unwrap();
    dlq.add_dead_letter(message2, "Failure 2".to_string(), None).await.unwrap();
    
    // 第三条消息应该失败（超过容量）
    let result = dlq.add_dead_letter(message3, "Failure 3".to_string(), None).await;
    assert!(result.is_err());
}

#[test]
fn test_retry_delay_strategies() {
    let fixed = RetryDelayStrategy::Fixed { delay_secs: 10 };
    let linear = RetryDelayStrategy::Linear { 
        initial_delay_secs: 5, 
        increment_secs: 3 
    };
    let exponential = RetryDelayStrategy::Exponential { 
        initial_delay_secs: 2, 
        max_delay_secs: 100, 
        multiplier: 3.0 
    };
    
    // 这些测试主要验证结构定义的完整性
    match fixed {
        RetryDelayStrategy::Fixed { delay_secs } => assert_eq!(delay_secs, 10),
        _ => panic!("Expected Fixed strategy"),
    }
    
    match linear {
        RetryDelayStrategy::Linear { initial_delay_secs, increment_secs } => {
            assert_eq!(initial_delay_secs, 5);
            assert_eq!(increment_secs, 3);
        },
        _ => panic!("Expected Linear strategy"),
    }
    
    match exponential {
        RetryDelayStrategy::Exponential { initial_delay_secs, max_delay_secs, multiplier } => {
            assert_eq!(initial_delay_secs, 2);
            assert_eq!(max_delay_secs, 100);
            assert_eq!(multiplier, 3.0);
        },
        _ => panic!("Expected Exponential strategy"),
    }
}

#[test]
fn test_alert_levels() {
    assert_eq!(AlertLevel::Info, AlertLevel::Info);
    assert_ne!(AlertLevel::Warning, AlertLevel::Error);
    assert_ne!(AlertLevel::Error, AlertLevel::Critical);
}

#[tokio::test]
async fn test_dead_letter_config_default() {
    let config = DeadLetterConfig::default();
    
    assert!(config.enabled);
    assert_eq!(config.max_retry_attempts, 3);
    assert_eq!(config.max_dead_letter_messages, 10000);
    assert_eq!(config.message_ttl_secs, 7 * 24 * 3600); // 7天
    assert!(config.enable_alerts);
    assert!(config.auto_retry);
    
    // 验证告警阈值
    assert_eq!(config.alert_thresholds.dead_letter_count_threshold, 1000);
    assert_eq!(config.alert_thresholds.error_rate_threshold, 5.0);
    assert_eq!(config.alert_thresholds.check_interval_secs, 300);
}